/*
Author : Nguyen Van Ty
Email  : ngvanty03@gmail.com
Date   : 12/26/2010 

*/

using System;
using System.Collections.Generic;
using System.Text;
using log4net;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Common;
using Utility;
using BusinessObject;
using System.Xml;

namespace DataAccessLayer
{
    /// <summary>
    /// Define PhieuBanHangDao class. This class inherit from  PhieuBanHangDaoBase class.
    /// If you want add new function, you must define here.
    /// </summary>
    public class PhieuBanHangDao : PhieuBanHangDaoBase
    {
        private static ILog logger = null;
        #region Constructor
        /// <summary>
        /// Define Constructor.
        /// </summary>
        public PhieuBanHangDao() { }
        static PhieuBanHangDao()
        {
            // Init logger.
            logger = LoggingUtility.GetLogger(typeof(PhieuBanHangDao).FullName);
        }
        public static Boolean CommitPhieuBanHang(Int64 maPhieuBanHang, string updatedBy, DateTime updateDate)
        {
            PhieuBanHang objOldPhieuBan = Get(maPhieuBanHang);
            if (objOldPhieuBan == null)
                return false;
            if (objOldPhieuBan.IsCommit)
                return false;
            String methodName = "CommitPhieuBanHang";
            if (logger.IsDebugEnabled)
            {
                LoggingUtility.logMethodEntry(logger, methodName);
            }
            ManagerDao.BeginTransaction();
            DbCommand cmd = ManagerDao.GetStoredProcCommand("spCommitPhieuBanHang");
            //Add value "MaPhieuNhapHang"  paramater.
            ManagerDao.AddInParameter(cmd, "MaPhieuBanHang", DbType.Int64, objOldPhieuBan.MaPhieuBanHang);
            ManagerDao.AddInParameter(cmd, "SysUpdatedBy", DbType.String, updatedBy);
            ManagerDao.AddInParameter(cmd, "SysUpdatedDate", DbType.DateTime, updateDate);
            //add paramater store return value.        
            ManagerDao.AddParameter(cmd, "returnValue", DbType.Int32, ParameterDirection.ReturnValue, string.Empty, DataRowVersion.Default, null);
            try
            {

                ManagerDao.ExecuteNonQuery(cmd);
                Int32 id = Int32.Parse(ManagerDao.GetParameterValue(cmd, "returnValue").ToString());
                if (id > 0)//Successfull.
                {

                    List<ChiTietPhieuBanHangResult> lstOldData = ChiTietPhieuBanHangDao.GetByMaPhieuBanHang(objOldPhieuBan.MaPhieuBanHang);
                    if (lstOldData != null && lstOldData.Count > 0)
                    {
                        foreach (ChiTietPhieuBanHangResult objDetail in lstOldData)
                        {
                            //Update MatHangTonKho
                            MatHangTonKho objTonKho = new MatHangTonKho();
                            objTonKho.MaDonViTinh = objDetail.MaDonViTinh;
                            objTonKho.MaKho = objOldPhieuBan.MaKho;
                            objTonKho.MaMatHang = objDetail.MaMatHang;
                            objTonKho.SoLuongTon = objDetail.SoLuong;
                            if (!MatHangTonKhoDao.RemoveMatHangTonKho(objTonKho))
                            {
                                ManagerDao.Rollback();
                                return false;
                            }

                        }
                    }
                    ManagerDao.Commit();
                    return true;
                }
            }
            catch (Exception e)
            {
                //write error message to log file.
                logger.Error(methodName, e);
            }
            ManagerDao.Rollback();
            return false;

        }

        public static Int64 Insert(PhieuBanHang obj, KhachHang objKhachHang, List<ChiTietPhieuBanHang> lstChiTiet, List<PhieuThu> lstPhieuThu)
        {
            Int64 id = 0;
            String methodName = "InsertPhieuBanHang";
            if (logger.IsDebugEnabled)
            {
                LoggingUtility.logMethodEntry(logger, methodName);
            }
            ManagerDao.BeginTransaction();
            //insert Khach hang
            int maKH = KhachHangDao.Insert(objKhachHang);
            if (maKH <= 0)
            {
                ManagerDao.Rollback();
                return 0;
            }
            DbCommand cmd = ManagerDao.GetStoredProcCommand("spInsertPhieuBanHang");

            //Add value "NgayBan"  paramater.
            ManagerDao.AddInParameter(cmd, "NgayBan", DbType.DateTime,
                ConvertValueObject.CastObjValueToInsertDB(obj.NgayBan));
            //Add value "NguoiBan"  paramater.
            ManagerDao.AddInParameter(cmd, "NguoiBan", DbType.String,
                ConvertValueObject.CastObjValueToInsertDB(obj.NguoiBan));
            //Add value "TongGiaTien"  paramater.
            ManagerDao.AddInParameter(cmd, "TongGiaTien", DbType.Double,
                ConvertValueObject.CastObjValueToInsertDB(obj.TongGiaTien));
            //Add value "MaKho"  paramater.
            ManagerDao.AddInParameter(cmd, "MaKho", DbType.Int32,
                ConvertValueObject.CastObjValueToInsertDB(obj.MaKho));
            //Add value "MaKhachHang"  paramater.
            ManagerDao.AddInParameter(cmd, "MaKhachHang", DbType.Int32,
                ConvertValueObject.CastObjValueToInsertDB(maKH));
            //Add value "NguoiLapPhieu"  paramater.
            ManagerDao.AddInParameter(cmd, "NguoiLapPhieu", DbType.String,
                ConvertValueObject.CastObjValueToInsertDB(obj.NguoiLapPhieu));
            //Add value "NgayLapPhieu"  paramater.
            ManagerDao.AddInParameter(cmd, "NgayLapPhieu", DbType.DateTime,
                ConvertValueObject.CastObjValueToInsertDB(obj.NgayLapPhieu));
            //////////////////////
            ManagerDao.AddInParameter(cmd, "SysCreatedBy", DbType.String,
               ConvertValueObject.CastObjValueToInsertDB(obj.SysCreatedBy));
            //Add value "NgayLapPhieu"  paramater.
            ManagerDao.AddInParameter(cmd, "SysCreatedDate", DbType.DateTime,
                ConvertValueObject.CastObjValueToInsertDB(obj.SysCreatedDate));
            //////////////////////
            ManagerDao.AddInParameter(cmd, "SysUpdatedBy", DbType.String,
               ConvertValueObject.CastObjValueToInsertDB(obj.SysUpdatedBy));
            //Add value "NgayLapPhieu"  paramater.
            ManagerDao.AddInParameter(cmd, "SysUpdatedDate", DbType.DateTime,
                ConvertValueObject.CastObjValueToInsertDB(obj.SysUpdatedDate));

            ManagerDao.AddInParameter(cmd, "IsCommit", DbType.Boolean, obj.IsCommit);
            ManagerDao.AddInParameter(cmd, "IsVAT", DbType.Boolean, obj.IsVAT);
            ManagerDao.AddInParameter(cmd, "VAT", DbType.Double,
               ConvertValueObject.CastObjValueToInsertDB(obj.VAT));
            ManagerDao.AddInParameter(cmd, "MaSoPhieu", DbType.String,
              ConvertValueObject.CastObjValueToInsertDB(obj.MaSoPhieu));
            //add paramater store return value.        
            ManagerDao.AddParameter(cmd, "returnValue", DbType.Int64, ParameterDirection.ReturnValue, string.Empty, DataRowVersion.Default, null);
            try
            {
                ManagerDao.ExecuteNonQuery(cmd);
                id = Int64.Parse(ManagerDao.GetParameterValue(cmd, "returnValue").ToString());
                if (id > 0)//Successfull.
                {
                    //insert list Detail
                    if (lstChiTiet != null && lstChiTiet.Count > 0)
                    {
                        foreach (ChiTietPhieuBanHang objChiTiet in lstChiTiet)
                        {
                            //kiem tra so luong nhap nho hon so luong ton
                            int soLuongTon = MatHangDao.GetSoLuongTonByDonViTinh(objChiTiet.MaMatHang, obj.MaKho, objChiTiet.MaDonViTinh);
                            if (soLuongTon < objChiTiet.SoLuong)
                            {
                                ManagerDao.Rollback();
                                return 0;
                            }
                            objChiTiet.MaPhieuBanHang = id;
                            if (!ChiTietPhieuBanHangDao.Insert(objChiTiet))
                            {
                                ManagerDao.Rollback();
                                return 0;
                            }
                            if (obj.IsCommit)
                            {
                                //Update MatHangTonKho
                                MatHangTonKho objTonKho = new MatHangTonKho();
                                objTonKho.MaDonViTinh = objChiTiet.MaDonViTinh;
                                objTonKho.MaKho = obj.MaKho;
                                objTonKho.MaMatHang = objChiTiet.MaMatHang;
                                objTonKho.SoLuongTon = objChiTiet.SoLuong;
                                if (!MatHangTonKhoDao.RemoveMatHangTonKho(objTonKho))
                                {
                                    ManagerDao.Rollback();
                                    return 0;
                                }
                            }
                        }
                        //insert phieu thu
                        if (lstPhieuThu != null && lstPhieuThu.Count > 0)
                        {
                            foreach (PhieuThu objPhieuThu in lstPhieuThu)
                            {
                                objPhieuThu.MaPhieuBanHang = id;
                                objPhieuThu.CreatedBy = obj.SysCreatedBy;
                                objPhieuThu.CreatedDate = objPhieuThu.NgayThu = obj.SysCreatedDate;
                                objPhieuThu.LastUpdatedBy = obj.SysUpdatedBy;
                                objPhieuThu.LastUpdatedDate = obj.SysUpdatedDate;
                                objPhieuThu.NguoiThu = obj.NguoiLapPhieu;
                                if (!PhieuThuDao.InsertUpdate(objPhieuThu))
                                {
                                    ManagerDao.Rollback();
                                    return 0;
                                }
                            }
                        }
                        ManagerDao.Commit();
                        return id;
                    }
                }
            }
            catch (Exception e)
            {
                //write error message to log file.
                logger.Error(methodName, e);
            }
            ManagerDao.Rollback();
            return id;
        }
        public static bool Update(PhieuBanHang obj, KhachHang objKhachHang, List<ChiTietPhieuBanHang> lstChiTiet, List<PhieuThu> lstPhieuThu)
        {

            String methodName = "UpdatePhieuBanHang";
            if (logger.IsDebugEnabled)
            {
                LoggingUtility.logMethodEntry(logger, methodName);
            }
            // List<ChiTietPhieuBanHangResult> lstChiTietOld = ChiTietPhieuBanHangDao.GetByMaPhieuBanHang(obj.MaPhieuBanHang);

            ManagerDao.BeginTransaction();

            DbCommand cmd = ManagerDao.GetStoredProcCommand("spUpdatePhieuBanHang");
            //Add value "MaPhieuBanHang"  paramater.
            ManagerDao.AddInParameter(cmd, "MaPhieuBanHang", DbType.Int64, obj.MaPhieuBanHang);
            //Add value "NgayBan"  paramater.
            ManagerDao.AddInParameter(cmd, "NgayBan", DbType.DateTime, ConvertValueObject.CastObjValueToInsertDB(obj.NgayBan));
            //Add value "NguoiBan"  paramater.
            ManagerDao.AddInParameter(cmd, "NguoiBan", DbType.String, ConvertValueObject.CastObjValueToInsertDB(obj.NguoiBan));
            //Add value "TongGiaTien"  paramater.
            ManagerDao.AddInParameter(cmd, "TongGiaTien", DbType.Double, obj.TongGiaTien);
            //Add value "MaKho"  paramater.
            ManagerDao.AddInParameter(cmd, "MaKho", DbType.Int32, obj.MaKho);
            //Add value "MaKhachHang"  paramater.
            ManagerDao.AddInParameter(cmd, "MaKhachHang", DbType.Int32, obj.MaKhachHang);
            //Add value "NguoiLapPhieu"  paramater.
            ManagerDao.AddInParameter(cmd, "NguoiLapPhieu", DbType.String, obj.NguoiLapPhieu);
            //Add value "NgayLapPhieu"  paramater.
            ManagerDao.AddInParameter(cmd, "NgayLapPhieu", DbType.DateTime, ConvertValueObject.CastObjValueToInsertDB(obj.NgayLapPhieu));

            //Add value "SysUpdatedBy"  paramater.
            ManagerDao.AddInParameter(cmd, "SysUpdatedBy", DbType.String, obj.SysUpdatedBy);
            //Add value "SysUpdatedDate"  paramater.
            ManagerDao.AddInParameter(cmd, "SysUpdatedDate", DbType.DateTime, ConvertValueObject.CastObjValueToInsertDB(obj.SysUpdatedDate));
            ManagerDao.AddInParameter(cmd, "IsCommit", DbType.Boolean, obj.IsCommit);
            ManagerDao.AddInParameter(cmd, "IsVAT", DbType.Boolean, obj.IsVAT);
            ManagerDao.AddInParameter(cmd, "VAT", DbType.Double,
               ConvertValueObject.CastObjValueToInsertDB(obj.VAT));
            // add parameter store return value.
            ManagerDao.AddParameter(cmd, "returnValue", DbType.Int32, ParameterDirection.ReturnValue, string.Empty, DataRowVersion.Default, null);
            try
            {
                ManagerDao.ExecuteNonQuery(cmd);
                int rows = (int)ManagerDao.GetParameterValue(cmd, "returnValue");
                if (rows >= 1)//Successfull.
                {
                    //rollback old data
                    //foreach (ChiTietPhieuBanHangResult objOldDetail in lstChiTietOld)
                    //{
                    //    //Update MatHangTonKho
                    //    MatHangTonKho objTonKho = new MatHangTonKho();
                    //    objTonKho.MaDonViTinh = objOldDetail.MaDonViTinh;
                    //    objTonKho.MaKho = obj.MaKho;
                    //    objTonKho.MaMatHang = objOldDetail.MaMatHang;
                    //    objTonKho.SoLuongTon = objOldDetail.SoLuong;
                    //    if (!MatHangTonKhoDao.RollBackMatHangTonKho(objTonKho))
                    //    {
                    //        ManagerDao.Rollback();
                    //        return false;
                    //    }
                    //}
                    //delete old data
                    if (!ChiTietPhieuBanHangDao.DeleteByMaPhieuBan(obj.MaPhieuBanHang))
                    {
                        ManagerDao.Rollback();
                        return false;
                    }
                    //uPDATE KhachHang
                    if (!KhachHangDao.Update(objKhachHang))
                    {
                        ManagerDao.Rollback();
                        return false;
                    }
                    //reinsert new data
                    if (lstChiTiet != null && lstChiTiet.Count > 0)
                    {
                        foreach (ChiTietPhieuBanHang objChiTiet in lstChiTiet)
                        {
                            //kiem tra so luong nhap nho hon so luong ton
                            int soLuongTon = MatHangDao.GetSoLuongTonByDonViTinh(objChiTiet.MaMatHang, obj.MaKho, objChiTiet.MaDonViTinh);
                            if (soLuongTon < objChiTiet.SoLuong)
                            {
                                ManagerDao.Rollback();
                                return false;
                            }
                            objChiTiet.MaPhieuBanHang = obj.MaPhieuBanHang;
                            if (!ChiTietPhieuBanHangDao.Insert(objChiTiet))
                            {
                                ManagerDao.Rollback();
                                return false;
                            }
                            //Update MatHangTonKho
                            /* MatHangTonKho objTonKho = new MatHangTonKho();
                             objTonKho.MaDonViTinh = objChiTiet.MaDonViTinh;
                             objTonKho.MaKho = obj.MaKho;
                             objTonKho.MaMatHang = objChiTiet.MaMatHang;
                             objTonKho.SoLuongTon = objChiTiet.SoLuong;
                             if (!MatHangTonKhoDao.RemoveMatHangTonKho(objTonKho))
                             {
                                 ManagerDao.Rollback();
                                 return false;
                             }*/
                        }
                    }
                    //Delete old Phieuthu
                    List<PhieuThu> lstOldPT = PhieuThuDao.GetByMaPhieuBanHang(obj.MaPhieuBanHang);
                    if (!PhieuThuDao.DeleteByMaPhieuBanHang(obj.MaPhieuBanHang))
                    {
                        ManagerDao.Rollback();
                        return false;
                    }
                    //insert phieu thu
                    if (lstPhieuThu != null && lstPhieuThu.Count > 0)
                    {

                        foreach (PhieuThu objPhieuThu in lstPhieuThu)
                        {
                            objPhieuThu.MaPhieuBanHang = obj.MaPhieuBanHang;
                            objPhieuThu.CreatedBy = obj.SysCreatedBy;
                            objPhieuThu.CreatedDate = objPhieuThu.NgayThu = obj.SysCreatedDate;
                            objPhieuThu.LastUpdatedBy = obj.SysUpdatedBy;
                            objPhieuThu.LastUpdatedDate = obj.SysUpdatedDate;
                            objPhieuThu.NguoiThu = obj.NguoiLapPhieu;
                            if (objPhieuThu.MaPhieuThu > 0)
                            {
                                foreach (PhieuThu objOldPT in lstOldPT)
                                {
                                    if (objOldPT.MaPhieuThu == objPhieuThu.MaPhieuThu)
                                    {
                                        objPhieuThu.NgayThu = objOldPT.NgayThu;
                                        objPhieuThu.NguoiThu = objOldPT.NguoiThu;
                                        objPhieuThu.CreatedBy = objOldPT.CreatedBy;
                                        objPhieuThu.CreatedDate = objOldPT.CreatedDate;
                                        objPhieuThu.LastUpdatedBy = obj.SysUpdatedBy;
                                        objPhieuThu.LastUpdatedDate = obj.SysUpdatedDate;
                                        objPhieuThu.MaPhieuThu = Int64.MinValue;
                                        break;
                                    }
                                }                                
                            }
                            if (!PhieuThuDao.InsertUpdate(objPhieuThu))
                            {
                                ManagerDao.Rollback();
                                return false;
                            }
                        }
                    }
                    //commit here
                    ManagerDao.Commit();
                    return true;

                }
                else//Error.
                {
                    ManagerDao.Rollback();
                    return false;
                }

            }
            catch (Exception e)
            {
                //write error Message to log file.
                logger.Error(methodName, e);

            }
            ManagerDao.Rollback();
            return false;
        }
        public static Curency GetCurencyForPhieuBanHang(Int64 maPhieuBanHang)
        {
            Curency objResult = null;
            String methodName = "GetCurencyForPhieuBanHang";
            if (logger.IsDebugEnabled)
            {
                LoggingUtility.logMethodEntry(logger, methodName);
            }
            try
            {

                DbCommand dbCommnand = ManagerDao.GetStoredProcCommand("spGetCurencyForPhieuBanHang");
                //Add value "MaPhieuBanHang"  paramater.
                ManagerDao.AddInParameter(dbCommnand, "MaPhieuBanHang", DbType.Int64, maPhieuBanHang);
                IDataReader reader = ManagerDao.ExecuteReader(dbCommnand);
                if (reader.Read())
                {
                    objResult = CurencyDao.GetCurencyByDataReader(reader);
                }
                reader.Close();
            }
            catch (System.Exception e)
            {
                //write error message to log file.
                logger.Error(methodName, e);
            }
            return objResult;
        }
        public static string GenerateCode(string currentCode, DateTime currentDate)
        {
            string id = string.Empty;
            String methodName = "GenerateCode";
            if (logger.IsDebugEnabled)
            {
                LoggingUtility.logMethodEntry(logger, methodName);
            }
            DbCommand cmd = ManagerDao.GetStoredProcCommand("sp_Generate_MaSoPhieuBanHang");
            ManagerDao.AddInParameter(cmd, "currentDate", DbType.DateTime,
                ConvertValueObject.CastObjValueToInsertDB(currentDate));
            ManagerDao.AddInParameter(cmd, "currentCode", DbType.String,
               ConvertValueObject.CastObjValueToInsertDB(currentCode));
            //add paramater store return value.        
            //   ManagerDao.AddParameter(cmd, "returnValue", DbType.String, ParameterDirection.ReturnValue, string.Empty, DataRowVersion.Default, null);
            try
            {
                IDataReader reader = ManagerDao.ExecuteReader(cmd);
                if (reader.Read())
                {
                    id = reader.GetValue(0).ToString();
                }
                reader.Close();
                return id;
            }
            catch (Exception e)
            {
                //write error message to log file.
                logger.Error(methodName, e);
            }
            return string.Empty;
        }
    }
}
        #endregion